package net.wangds.spring.utils;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.Collection;
import java.util.Locale;
import java.util.function.Supplier;

@Component
@Order(20)
public class SpringUtils implements ApplicationContextAware {

    private static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;

    private static ApplicationContext applicationContext;
    // 获取applicationContext
    @SuppressWarnings("WeakerAccess")
    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    // 通过name获取 Bean.
    @SuppressWarnings("unchecked")
    public static <T>  T getBean(String name) {
        return (T)getApplicationContext().getBean(name);
    }

    @SuppressWarnings("unchecked")
    public static <T> T getBean(String name, Object ... args) {
        return (T)getApplicationContext().getBean(name, args);
    }

    // 通过class获取Bean.
    @SuppressWarnings("unused")
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }


    public static <T> T getBean(Class<T> clazz, Object ... args) {
        return getApplicationContext().getBean(clazz, args);
    }

    public static <T> Collection<T> getBeansOfType(Class<T> clazz) {
        return getApplicationContext().getBeansOfType(clazz).values();
    }
    // 通过name,以及Clazz返回指定的Bean
    @SuppressWarnings("unused")
    public static <T> T getBean(String name, Class<T> clazz) {
        return getApplicationContext().getBean(name, clazz);
    }


    @SuppressWarnings("unused")
    public static String getProperty(String name, String defaultValue){
        return getApplicationContext().getMessage(name, new Object[0], defaultValue, DEFAULT_LOCALE);
    }

    public static String getMessage(String name, Object[] args, String defaultValue, Locale locale){
        return getApplicationContext().getMessage(name, args==null?new Object[0]:args, defaultValue, locale==null?DEFAULT_LOCALE:locale);
    }

    public static String getMessage(String name, Object[] args, Supplier<String> defaultValueSupplier, Locale locale){
        String res = getApplicationContext().getMessage(name, args==null?new Object[0]:args, null, locale==null?DEFAULT_LOCALE:locale);
        if(res==null&&defaultValueSupplier!=null){
            res = defaultValueSupplier.get();
        }
        return res;
    }

    public static String getMessage(String name, Object[] args, Locale locale){
        return getMessage(name, args, "", locale);
    }

    public static String getMessage(String name, Object[] args, String defaultValue){
        return getMessage(name, args, defaultValue,null);
    }

    public static String getMessage(String name, Object[] args, Supplier<String> defaultValueSupplier){
        return getMessage(name, args, defaultValueSupplier,null);
    }

    public static String getMessage(String name, Locale locale){
        return getMessage(name, null, "", locale);
    }

    public static String getMessage(String name, String defaultValue){
        return getMessage(name, null, defaultValue, null);
    }

    public static String getMessage(String name){
        return getMessage(name,null, "", null);
    }


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if (SpringUtils.applicationContext == null) {
            SpringUtils.applicationContext = applicationContext;
        }
    }

    /**
     * 从环境变量或Application.properties获取配置.
     * @param key key.
     * @param defaultVal 默认值.
     * @return 结果.
     */
    public static String getSysEnvOrSpringEvnOption(String key, String defaultVal){
        String val = System.getenv(key);
        Environment env = getBean(Environment.class);
        if(StringUtils.isBlank(val)){
            val = env.getProperty(key, defaultVal); //从application.properties中获取.
        }
        val = StringUtils.trim(val);
        return val;
    }



}
